package net.sudot.commons.security;

import net.sudot.commons.utils.WebUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationToken;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * 认证过滤器
 *
 * @author tangjialin on 2017-06-14 0014.
 */
public class JwtAuthenticationFilter extends AuthenticationFilter {
    /** 用户TOKEN Header名称 */
    public static final String USER_TOKEN_PARAMETER_NAME = "token";
    /** 用户TOKEN Header名称 */
    public static final String USER_TOKEN_HEADER_NAME = "X-USER-TOKEN";
    /** 用户TOKEN Cookie名称 */
    public static final String USER_TOKEN_COOKIE_NAME = "USER-TOKEN";
    /** 密钥 */
    private String secret;

    public JwtAuthenticationFilter(Class<?> userClass, String secret) {
        super(userClass);
        this.secret = secret;
    }

    @Override
    protected org.apache.shiro.authc.AuthenticationToken createToken(ServletRequest servletRequest, ServletResponse servletResponse) {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String userToken = getToken(request);
        if (userToken == null) {
            return super.createToken(servletRequest, servletResponse);
        } else {
            return new JwtUserAuthenticationToken(getUserClass(), Jwt.verify(userToken, secret), null, isRememberMe(request), getHost(request));
        }
    }

    @Override
    protected AuthenticationToken createToken(String username, String password, boolean rememberMe, String host) {
        return new JwtUserAuthenticationToken(getUserClass(), new Jwt.Payload(username), password, rememberMe, host);
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object mappedValue) {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String userToken = getToken(request);
        if (StringUtils.isEmpty(userToken)) { return false; }
        Jwt.Payload payload = Jwt.verify(userToken, secret);
        if (payload == null) { return false; }
        servletRequest.setAttribute(Jwt.Payload.class.getSimpleName(), payload);
        return true;
    }

    /**
     * 获取token信息
     *
     * @param request HttpServletRequest
     * @return 返回token内容
     */
    protected String getToken(HttpServletRequest request) {
        String userToken = request.getParameter(USER_TOKEN_PARAMETER_NAME);
        if (StringUtils.isNotEmpty(userToken)) { return userToken; }
        userToken = request.getHeader(USER_TOKEN_HEADER_NAME);
        if (StringUtils.isNotEmpty(userToken)) { return userToken; }
        userToken = WebUtils.getCookie(request, USER_TOKEN_COOKIE_NAME);
        if (StringUtils.isNotEmpty(userToken)) { return userToken; }
        return userToken;
    }
}